package org.iks.common.aop.serializer;

import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
import org.iks.common.aop.OrderField;
import org.iks.common.aop.OrderFields;
import org.iks.common.constant.SortType;

import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

/**
 * Author kzou
 * Date 2023/12/17 20:40
 * Description: {@link OrderFields} 处理器
 * data format example : "paramName1:desc,paramName2:asc"
 */
public class OrderFieldsDeserializer extends JsonDeserializer<Map<String, SortType>> implements ContextualDeserializer {

    private OrderFields annotation;

    @Override
    public Map<String, SortType> deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
        String text = jsonParser.getText();
        OrderField[] orderFields = annotation.mappingFields();
        String fieldSeparator = annotation.fieldSeparator();
        String orderFieldSeparator = annotation.orderFieldSeparator();
        boolean camelCaseToUnderline = annotation.camelCaseToUnderline();
        String[] fields = text.split(fieldSeparator);
        if (fields.length == 0) {
            return Collections.emptyMap();
        }
        HashMap<String, SortType> result = new HashMap<>();
        Map<String, OrderParam> paramMap = orderFieldMapping(orderFields);
        for (String field : fields) {
            String[] item = field.split(orderFieldSeparator);
            String paramName = item[0];
            // 排序规则说明： 默认先获取用户参数指明的排序方式，如果没有者获取 OrderField 默认的排序方式;
            // 若没有 OrderField，则获取 OrderFields 默认的排序方式
            SortType sortType = item.length > 1 ? SortType.parse(item[1]) : null;
            OrderParam orderParam = paramMap.get(paramName);
            if (orderParam != null) {
                sortType = sortType == null ? orderParam.sortType : sortType;
                paramName = orderParam.filedName;
            }
            if (sortType == null) {
                // 使用默认的排序方式
                sortType = annotation.defaultSortType();
            }
            if (camelCaseToUnderline) {
                paramName = StrUtil.toUnderlineCase(paramName);
            }
            result.put(paramName, sortType);
        }
        return result;
    }

    Map<String, OrderParam> orderFieldMapping(OrderField[] orderFields) {
        if (orderFields == null || orderFields.length == 0) {
            return Collections.emptyMap();
        }
        HashMap<String, OrderParam> result = new HashMap<>();
        for (OrderField orderField : orderFields) {
            SortType sortType = orderField.defaultSortType();
            OrderParam orderParam = new OrderParam(orderField.fieldName(), orderField.paramName(), sortType);
            result.put(orderField.paramName(), orderParam);
        }
        return result;
    }

    @Override
    public JsonDeserializer<?> createContextual(DeserializationContext deserializationContext, BeanProperty beanProperty) throws JsonMappingException {
        annotation = beanProperty.getAnnotation(OrderFields.class);
        return this;
    }

    static class OrderParam {
        String filedName;
        String paramName;
        SortType sortType;

        public OrderParam(String fieldName, String paramName, SortType sortType) {
        }
        public String getFiledName() {
            return filedName;
        }

        public String getParamName() {
            return paramName;
        }

        public SortType getSortType() {
            return sortType;
        }
    }

}
